#!/usr/bin/env python
# encoding: utf-8
"""
entry_tests.py

Created by Igor Foox on 2007-02-04.
Copyright (c) 2007 Igor Foox. All rights reserved.
"""

import sys
import os
import unittest
from gcapi import entry
import datetime

entryXML = \
"""<?xml version='1.0' encoding='UTF-8'?>

<feed xmlns='http://www.w3.org/2005/Atom'
	xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
	xmlns:gd='http://schemas.google.com/g/2005'
	xmlns:gCal='http://schemas.google.com/gCal/2005'>
<entry>
	<id>
	    http://www.google.com/calendar/feeds/default/private/full/dv42fuv1b4rfkmc47s1orahnco
	</id>
	<published>2006-11-05T15:07:52.000Z</published>
	<updated>2006-11-05T15:08:07.000Z</updated>
	<category scheme='http://schemas.google.com/g/2005#kind'
		term='http://schemas.google.com/g/2005#event'>
	</category>
	<title type='text'>Test Reminder 1 Woche</title>
	<content type='text'></content>
	<link rel='alternate' type='text/html'
		href='http://www.google.com/calendar/event?eid=ZHY0MmZ1djFiNHJma21jNDdzMW9yYWhuY28gbWFydGluLm1vZWxsZW5iZWNrQGdvb2dsZW1haWwuY29t'
		title='alternate'>
	</link>
	<link rel='self' type='application/atom+xml'
		href='http://www.google.com/calendar/feeds/default/private/full/dv42fuv1b4rfkmc47s1orahnco'>
	</link>
	<link rel='edit' type='application/atom+xml'
		href='http://www.google.com/calendar/feeds/default/private/full/dv42fuv1b4rfkmc47s1orahnco/63298422487'>
	</link>
	<author>
		<name>Martin Möllenbeck</name>
		<email>martin.moellenbeck@googlemail.com</email>
	</author>
	<gd:visibility
		value='http://schemas.google.com/g/2005#event.default'>
	</gd:visibility>
	<gd:comments>
		<gd:feedLink
			href='http://www.google.com/calendar/feeds/default/private/full/dv42fuv1b4rfkmc47s1orahnco/comments'>
		</gd:feedLink>
	</gd:comments>
	<gd:transparency
		value='http://schemas.google.com/g/2005#event.opaque'>
	</gd:transparency>
	<gd:eventStatus
		value='http://schemas.google.com/g/2005#event.confirmed'>
	</gd:eventStatus>
	<gCal:sendEventNotifications value='true'></gCal:sendEventNotifications>
	<gd:where valueString=''></gd:where>
	<gd:when startTime='%s' endTime='%s'>
		<gd:reminder minutes='10080'></gd:reminder>
	</gd:when>
</entry>
</feed>
"""

class ParseXsDateTimeTests(unittest.TestCase):
    """
    Tests the Entry._parseXsDateTime() method.
    """
    def test_simpleDateOnes(self):
        ent = entry.Entry()
        theDate = ent._parseXsDateTime("0001-01-01")
        assert type(theDate) == datetime.date
        assert theDate.year == 1
        assert theDate.month == 1
        assert theDate.day == 1
    def test_simpleDateMax(self):
        ent = entry.Entry()
        theDate = ent._parseXsDateTime("%i-%i-%i" % (datetime.datetime.max.year,
                                                    datetime.datetime.max.month,
                                                    datetime.datetime.max.day)
                                        )
        assert type(theDate) == datetime.date
        assert theDate.year == datetime.datetime.max.year
        assert theDate.month == datetime.datetime.max.month
        assert theDate.day == datetime.datetime.max.day
    
    def test_simpleDateOverMax(self):
        ent = entry.Entry()
        try:
            theDate = ent._parseXsDateTime("%i-%i-%i" % (datetime.datetime.max.year ,
                                                    datetime.datetime.max.month + 1,
                                                    datetime.datetime.max.day + 1)
                                        )
        except:
            return
            
        self.fail("A date greater than 9999-12-31 is invalid.")

    def test_simpleDateZeroYear(self):
        ent = entry.Entry()
        try:
            theDate = ent._parseXsDateTime("0000-01-01")
        except ValueError:
            return
        
        self.fail("Parsing a date with a year of 0 should throw an error.")


    def test_simpleDateZeroMonth(self):
        ent = entry.Entry()
        try:
            theDate = ent._parseXsDateTime("2000-00-07")
        except ValueError:
            return
            
        self.fail("Parsing a date with a month of 0 should throw an error.")

    def test_simpleDateZeroDay(self):
        ent = entry.Entry()
        try:
            theDate = ent._parseXsDateTime("2000-06-00")
        except ValueError:
            return

        self.fail("Parsing a date with a day of 0 should throw an error.")
        
    def test_simpleDateShortYearLength(self):
        ent = entry.Entry()
        try:
            theDate = ent._parseXsDateTime("123-12-14")
        except ValueError:
            return
            
        fail("Year length should be 4 characters.")
        
    def test_simpleDatetimeZeroYear(self):
        ent = entry.Entry()
        try:
            theDate = ent._parseXsDateTime("0000-01-01T18:12:14")
        except ValueError:
            return
        
        self.fail("Parsing a datetime with a year of 0 should throw an error.")
    def test_simpleDatetimeZeroMonth(self):
        ent = entry.Entry()
        try:
            theDate = ent._parseXsDateTime("0001-00-01T18:12:14")
        except ValueError:
            return
        
        self.fail("Parsing a datetime with a month of 0 should throw an error.")

    def test_simpleDatetimeZeroDay(self):
        ent = entry.Entry()
        try:
            theDate = ent._parseXsDateTime("2004-01-00T18:12:14")
        except ValueError:
            return
        
        self.fail("Parsing a datetime with a day of 0 should throw an error.")
        

class ApplyWhenTests(unittest.TestCase):
    """
    Tests the Entry.applyWhen() method.
    """
        
    def test_TwoValidDates(self):
        """
        Test an entry where both startTime and endTime are valid dates (i.e. YYYY-MM-DD).
        """
        self.entry = entry.Entry.createFromText(entryXML % ("2006-10-12", "2004-01-01"))[0]
        
        assert type(self.entry.startTime) == datetime.date
        assert self.entry.startTime.year == 2006
        assert self.entry.startTime.month == 10        
        assert self.entry.startTime.day == 12

        assert type(self.entry.endTime) == datetime.date
        assert self.entry.endTime.year == 2004
        assert self.entry.endTime.month == 01       
        assert self.entry.endTime.day == 01

    def test_TypeMismatchEndDatetime(self):
        """
        Test an entry where startTime is a datetime and endTime is a date.
        """
        self.entry = entry.Entry.createFromText(entryXML % ("2006-01-01", "2006-11-05T15:06:08.123Z"))[0]

        assert type(self.entry.startTime) == datetime.date
        assert self.entry.startTime.year == 2006
        assert self.entry.startTime.month == 01        
        assert self.entry.startTime.day == 01

        assert type(self.entry.endTime) == datetime.date
        assert self.entry.endTime.year == 2006
        assert self.entry.endTime.month == 11      
        assert self.entry.endTime.day == 05

    def test_NoneEndTime(self):
        """
        Test an entry where startTime is a date endTime is empty. endTime should
        become None in python.
        """
        self.entry = entry.Entry.createFromText(entryXML % ("2006-01-01", ""))[0]

        assert type(self.entry.startTime) == datetime.date
        assert self.entry.startTime.year == 2006
        assert self.entry.startTime.month == 01        
        assert self.entry.startTime.day == 01
        
        assert self.entry.endTime is None

    def test_TypeMismatchEndDate(self):
        """
        Test an entry where startTime is a datetime and endTime is a date. endTime
        should be converted to a datetime.
        """
        self.entry = entry.Entry.createFromText(entryXML % ("2006-07-05T15:06:08.000Z", "2006-10-01"))[0]

        assert type(self.entry.startTime) == datetime.datetime
        assert self.entry.startTime.year == 2006
        assert self.entry.startTime.month == 07       
        assert self.entry.startTime.day == 05
        
        assert type(self.entry.endTime) == datetime.datetime
        assert self.entry.endTime.year == 2006
        assert self.entry.endTime.month == 10
        assert self.entry.endTime.day == 01
if __name__ == '__main__':
    unittest.main()